feat(advisory): resolve pending advisory choices through the autonomy ladder (#2253 Bolt advisory-auto-resolution) - #2318
Conversation
|
Warning Review limit reached
Next review available in: 19 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (19)
📝 WalkthroughWalkthrough自律性を Changes自律性と Advisory 処理
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2c42d13. Configure here.
| identity: pending.identity, | ||
| choice, | ||
| humanTurn, | ||
| provenance, |
There was a problem hiding this comment.
Auto receipts mis-bind multiple pendings
High Severity
Unattended advisory resolution can write auto-decision receipts for every open pending while grounding only checks that one pending matches a single journal decision. The orchestrator also records only the first ladder outcome after committing separate decisions per held advisory. Other instances can appear resolved with another advisory’s decisionId, bypassing per-instance occurrence binding.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 2c42d13. Configure here.
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/framework/core/tools/amadeus-intent-autonomy.ts`:
- Around line 179-185: Add a configuration path for
AutonomyProjection.semiPolicies so semi-mode resolveConfirmedPolicy receives
policies during normal human commands. Update createAutonomyProjection and
planHumanAutonomyCommand, or the existing replay/migration flow, to preserve and
populate semiPolicies when policies are available; keep semiPoliciesOf returning
an empty list when none are configured.
- Around line 545-548: Update allowsOccurrence to require that occurrence.kind
is included in SEMI_ROUTINE_INTERACTIONS in addition to the existing authority
scope checks, so unvalidated semiScope.allowedInteractionKinds cannot authorize
walking-skeleton or phase-gate interactions.
- Around line 553-562: Update authorizeEffect to reject the request when
currentNormFingerprint differs from _authority.scope.normFingerprint, in
addition to the existing effect classification and applicableNormFingerprint
checks. Preserve the current unauthorized result and successful authorization
behavior for matching authority and effect norms.
In `@tests/integration/t-advisory-human-choice-boundaries.test.ts`:
- Around line 51-62:
各テストファイルに重複しているrecordAdvisoryChoiceViaPromptヘルパーをtests/integration/t-advisory-human-choice-boundaries.test.tsの51-62行、tests/integration/t-advisory-choice-record.test.tsの56-72行、tests/integration/t445-advisory-declaration-supply.integration.test.tsの38-49行から削除し、tests/harness/に共有実装を1つ追加して、3ファイルでそれをimportして利用する。
In `@tests/integration/t-advisory-human-choice-domain.test.ts`:
- Around line 66-72: Extend the test “receipt parserは完全なprovenanceだけを受理する” with
one auto-decision provenance case that exercises provenanceProblem’s
auto-decision validation, including decisionId, basisKind, basisFingerprint,
projectionRevision, phase, and graphRevision, and assert the parser accepts a
complete valid arm while preserving the existing human-turn and unknown-kind
rejection cases.
In `@tests/integration/t458-advisory-auto-resolution.integration.test.ts`:
- Around line 283-301: Update the test around resolveAdvisoryChoiceAutonomously
to assert the expected resolution kind before attempting to record the
auto-decision; if the intended result is human-required, also assert its reason
explicitly. Keep the FR-ADV-3 duplicate-receipt assertion unconditional after
that precondition so the test always verifies that a second auto-decision cannot
be recorded.
In `@tests/unit/t457-advisory-auto-resolve.test.ts`:
- Around line 146-157: In the test case constructing the decided
AutonomyDecisionResult, bind the expected decision value to a local variable
before the assertion, then use that variable for the expected decision field
instead of the result.kind conditional expression. Keep the expected resolved
output and all other assertions unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 2b6b1795-94ea-47d9-862a-1897d98b7a26
📒 Files selected for processing (30)
packages/framework/core/hooks/amadeus-mint-presence.tspackages/framework/core/hooks/amadeus-statusline.tspackages/framework/core/tools/amadeus-advisory-choice.tspackages/framework/core/tools/amadeus-intent-autonomy-production.tspackages/framework/core/tools/amadeus-intent-autonomy-runtime.tspackages/framework/core/tools/amadeus-intent-autonomy.tspackages/framework/core/tools/amadeus-lib.tspackages/framework/core/tools/amadeus-orchestrate.tspackages/framework/harness/codex/hooks/amadeus-codex-adapter.tstests/.coverage-patch-allowlist.jsontests/.coverage-ratchet.jsontests/.coverage-registry.jsontests/integration/t-advisory-choice-record.test.tstests/integration/t-advisory-human-choice-boundaries.test.tstests/integration/t-advisory-human-choice-domain.test.tstests/integration/t-coverage-mechanism-ratchet.test.tstests/integration/t432-intent-autonomy-runtime.integration.test.tstests/integration/t445-advisory-declaration-supply.integration.test.tstests/integration/t450-autonomy-flag-branch.test.tstests/integration/t453-semi-ladder-runtime.integration.test.tstests/integration/t458-advisory-auto-resolution.integration.test.tstests/unit/t203-mint-presence-classify.test.tstests/unit/t431-intent-autonomy.test.tstests/unit/t448-autonomy-statusline-segment.test.tstests/unit/t449-autonomy-flag-parse.test.tstests/unit/t450-autonomy-flag-apply.test.tstests/unit/t451-semi-authority.test.tstests/unit/t452-authorize-interaction-semi.test.tstests/unit/t457-advisory-auto-resolve.test.tstests/unit/t459-advisory-receipt.test.ts
| function recordAdvisoryChoiceViaPrompt( | ||
| projectDir: string, | ||
| prompt: string, | ||
| humanTurn: { timestamp: string; shard: string; eventIdentity: string }, | ||
| now?: string, | ||
| ): boolean { | ||
| const choice = choiceFromExactPrompt(prompt); | ||
| if (choice === null) return false; | ||
| return now === undefined | ||
| ? recordAdvisoryChoice(projectDir, choice, { kind: "human-turn", ...humanTurn }) | ||
| : recordAdvisoryChoice(projectDir, choice, { kind: "human-turn", ...humanTurn }, now); | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
recordAdvisoryChoiceViaPrompt が3ファイルに同一複製されている。 旧 prompt 分類 API の置き換えを各テストファイルで個別に再実装したことが共通の原因です。recordAdvisoryChoice のシグネチャが再度変わると3箇所が同時に壊れます。1箇所に集約してください。
tests/integration/t-advisory-human-choice-boundaries.test.ts#L51-L62: ヘルパーを削除し、tests/harness/の共有実装を import する。tests/integration/t-advisory-choice-record.test.ts#L56-L72: 同じヘルパー定義を削除し、共有実装を import する。tests/integration/t445-advisory-declaration-supply.integration.test.ts#L38-L49: 同じヘルパー定義を削除し、共有実装を import する。
📍 Affects 3 files
tests/integration/t-advisory-human-choice-boundaries.test.ts#L51-L62(this comment)tests/integration/t-advisory-choice-record.test.ts#L56-L72tests/integration/t445-advisory-declaration-supply.integration.test.ts#L38-L49
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/integration/t-advisory-human-choice-boundaries.test.ts` around lines 51
- 62,
各テストファイルに重複しているrecordAdvisoryChoiceViaPromptヘルパーをtests/integration/t-advisory-human-choice-boundaries.test.tsの51-62行、tests/integration/t-advisory-choice-record.test.tsの56-72行、tests/integration/t445-advisory-declaration-supply.integration.test.tsの38-49行から削除し、tests/harness/に共有実装を1つ追加して、3ファイルでそれをimportして利用する。
| const result: AutonomyDecisionResult = { | ||
| kind: "decided", | ||
| decision: decision("run-now", ["run-now"]), | ||
| effect: effect("run-now", "workflow-reversible"), | ||
| receipt, | ||
| }; | ||
| expect(translateAdvisoryDecision(result)).toEqual({ | ||
| kind: "resolved", | ||
| choice: "run-now", | ||
| decision: result.kind === "decided" ? result.decision : decision("run-now", ["run-now"]), | ||
| projectionRevision: 3, | ||
| }); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
期待値内の型絞り込み三項演算子は不要である。
decision を先に変数へ束縛すれば、Line 155 の分岐は消えます。テストの意図が読みやすくなります。
♻️ 提案
+ const decided = decision("run-now", ["run-now"]);
const result: AutonomyDecisionResult = {
kind: "decided",
- decision: decision("run-now", ["run-now"]),
+ decision: decided,
effect: effect("run-now", "workflow-reversible"),
receipt,
};
expect(translateAdvisoryDecision(result)).toEqual({
kind: "resolved",
choice: "run-now",
- decision: result.kind === "decided" ? result.decision : decision("run-now", ["run-now"]),
+ decision: decided,
projectionRevision: 3,
});📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const result: AutonomyDecisionResult = { | |
| kind: "decided", | |
| decision: decision("run-now", ["run-now"]), | |
| effect: effect("run-now", "workflow-reversible"), | |
| receipt, | |
| }; | |
| expect(translateAdvisoryDecision(result)).toEqual({ | |
| kind: "resolved", | |
| choice: "run-now", | |
| decision: result.kind === "decided" ? result.decision : decision("run-now", ["run-now"]), | |
| projectionRevision: 3, | |
| }); | |
| const decided = decision("run-now", ["run-now"]); | |
| const result: AutonomyDecisionResult = { | |
| kind: "decided", | |
| decision: decided, | |
| effect: effect("run-now", "workflow-reversible"), | |
| receipt, | |
| }; | |
| expect(translateAdvisoryDecision(result)).toEqual({ | |
| kind: "resolved", | |
| choice: "run-now", | |
| decision: decided, | |
| projectionRevision: 3, | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/unit/t457-advisory-auto-resolve.test.ts` around lines 146 - 157, In the
test case constructing the decided AutonomyDecisionResult, bind the expected
decision value to a local variable before the assertion, then use that variable
for the expected decision field instead of the result.kind conditional
expression. Keep the expected resolved output and all other assertions
unchanged.
|
レビュー観点の追記: 本 PR の FR-ADV-3 置き換え(schema 1 store を翻訳しない fail-closed)は、pending エントリが実在する既存 schema 1 store で「hold が人間に聞き直す」機構自体を起動不能にします(store 全体が parse 拒否になるため、pending の識別子ごと読めず、record verb も書けない)。本 intent の conductor 断面で決定的再現済み — 詳細と期待回復経路は Issue #2330 を参照してください。 |
96576b1 to
c34377d
Compare
… ladder An advisory raised at a checkpoint replaced the run-stage directive with a question for the human, so a single advisory ended an unattended run. The hold is now offered to the autonomy ladder first: mapped onto a question occurrence carrying the advisory instance, ruled through the existing production decision path, and — only when the ladder chose run-now — accepted as a receipt whose provenance is the ruling itself. Acceptance is one function over a provenance union rather than two routes: the human turn and the ladder decision clear the same three checks (grounding, single spend, presentation) at the same depth. The store moves to schema 2; an older store is not translated, it fails to parse and the existing arm holds. Refs #2253
The acceptance module is imported by the UserPromptSubmit mint hook on every human prompt, which holds a sub-300ms budget; loading the autonomy ladder there cost more than the budget allowed. The three bindings the unattended paths need are required at the call instead, so a human prompt pays for none of them. Refs #2253
…olution paths The patch gate flagged 14 added lines on the PR. Five are executable and now carry direct tests: the provenance projectionRevision validation arm, both unreadable-journal catch arms (acceptance and the ladder ruling), and the orchestrate pass-through that returns the original directive once the auto-decision receipt is accepted. The other nine are the multiline TypeScript input types of advisoryOccurrenceMatchesDecision and resolveAdvisoryChoiceAutonomously, which Bun stamps DA:0 only in the merged suite; they join the patch allowlist under the same type-only precedent as the goal-reconciliation entries. Refs #2253
400d4c1 to
b617c0e
Compare
… (#2372) Bring the workflow record for #2253 onto main: the build-and-test stage's seven artifacts, the construction phase-boundary check, the goal reconciliation items and receipt, the appended audit shard, and the terminal state. The registry row advances in-flight → complete. Implementation for this intent already landed in seven PRs (#2293, #2294, #2295, #2316, #2317, #2318, #2321); this commit carries the record only — no source or test changes. Evidence recorded in the artifacts (measured on the conductor clone, values transcribed from command output): - bash tests/run-tests.sh --ci: exit 0, RESULT: PASS (11,494 pass / 0 fail) - build / typecheck / lint / source-only:check / complexity-gate: exit 0 - declared sensors on the seven artifacts: FIRED 14 / PASSED 14 / FAILED 0 - requirement traceability: 33 of 33 ids trace into the construction tree - formal-model-check: NOT_DETECTED (correlated run, no counterexample) - goal reconciliation: goal-statement ACHIEVED over 14 digest-verified refs The audit shard is a pure append over main's copy (main's bytes verified as a byte-exact prefix); the registry keeps every other row untouched. Refs #2253


概要
Intent
260805-semi-redefine-autonomy-f(Issue #2253)の Construction Boltadvisory-auto-resolution(swarm batch 2)。pending advisory choice を autonomy 梯子(無人解決 5 段)経由で解決する C16/C17 連鎖を実装する。amadeus-advisory-choice.ts: C16 auto 解決連鎖(guardAdvisoryChoices解放後 →commitProductionQuestionDecision→recordAdvisoryChoice)+ C17amadeus-orchestrate.ts: two-branch guardamadeus-intent-autonomy-production.ts:effectClassificationsmap(optional)+PROHIBITED_EFFECTSexporthumanTurnから provenance union(schema 2)へ置き換え(FR-ADV-3並存させない— 旧名 grep 0)積み上げ(stacked PR)
本 PR は origin/main(
00da4bdda)+ batch 1 の 3 PR(#2293 / #2294 / #2295)のマージ(2b0da2153)を base に持つ。batch 1 の 3 PR が先にマージされるまで diff に batch 1 のコミットが含まれる。 マージ順: #2293/#2294/#2295 → 本 PR(着地後に再接地予定)。テスト(TDD Red→Green + 落ちる実証 ×3)
tests/unit/t457-advisory-auto-resolve.test.ts/tests/unit/t459-advisory-receipt.test.ts/tests/integration/t458-advisory-auto-resolution.integration.test.ts(新規、各 Red 実測記録あり)検証(builder 実測)
BUILD 0 / TYPECHECK 0 / LINT 0 / COMPLEXITY 0 / REGISTRY 0 / SOURCEONLY 0 / full
bash tests/run-tests.sh --ciPASS 861 files・11477 assertions・0 fail。allowlist 584 selector 全解決(stale 1 件は--create-selector再アンカー、span 23 行不変)。referee converged / finalize(batch 3)converged。申告(FD 逐語超過 2 点 — レビュー観点)
commitProductionQuestionDecisionへ optionaleffectClassifications— FD step 2 の effect registry(defer-with-risk=quality-waiver)は既存 adapter のハードコードでは執行不能で、欠くと副次バリアが検証劇場化するため(既定挙動は全既存呼び出しで不変)auto-decisionprovenance へphase・graphRevisionを追加搭載 — occurrence id が当該入力の digest のため、搭載により誤帰属が構造的に不能になる(全フィールドに消費者あり、t458/t459 で固定)既知の外部ブロッカー
「No silent drop (trusted base ratchet)」は main 側 reconcile の連続失敗(#2313)により本 PR と無関係に赤になる。#2313 解消待ち。
Refs #2253
Note
High Risk
Changes advisory acceptance, orchestration hold handling, and intent autonomy authorization paths; incorrect auto-resolution or provenance could let unattended runs proceed or block humans incorrectly.
Overview
Advisory choices move from human-turn-only receipts to a schema 2 store with a
human-turn|auto-decisionprovenance union.recordProtectedAdvisoryChoicebecomesrecordAdvisoryChoicewith unified acceptance (grounding, single-spend, presentation). Schema 1 on disk is not migrated—parse fails and the guard stays fail-closed.When
guardAdvisoryChoicesreturns a hold, orchestration triesresolveAdvisoryChoiceAutonomouslyfirst: each pending advisory goes throughcommitProductionQuestionDecisionas aquestioninteraction; only an acceptedrun-nowwith journal-groundedauto-decisionprovenance lets the originalrun-stagedirective continue. Anything else still emitsawait-advisory-choice. Autonomy modules are lazy-required in the advisory-choice module so mint hooks stay under budget.Semi autonomy is refactored from
semi-mode-gatetoSemiAuthority: caller-suppliedsemiScope, routine kindsstage-gate+question, andSemiAuthority.authorizeEffectfor reversible effects. Questions in semi use the full decision ladder (not gate auto-approve). Production commits take optionaleffectClassificationsper option (e.g.defer-with-risk→quality-waiver).CLI / UX:
parseNextFlags/applyLaunchAutonomyDeclarationadd--autonomy none|semi|fullwith fail-closed rules (no silent grant revoke, full needs issued grant, human provenance for writes). Statusline appends@none|semi|fullviaautonomySegmenton state file Intent Autonomy Mode.Reviewed by Cursor Bugbot for commit 2c42d13. Configure here.
Summary by CodeRabbit
新機能
--autonomyで自律性モード(none/semi/full)を指定できるようになりました。改善